/*
 * DefaultCategoryLoader.java
 *
 *  
 */
package org.msb.finance.data;

import java.io.Reader;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.msb.finance.res.CoreMessages;

/**
 * 
 * 
 * @author Marc
 * 
 */
public class CategoryLoader {

	/*
	 * 
	 */
	private static final String ELEM_INCOME = "income"; //$NON-NLS-1$
	/*
	 * 
	 */
	private static final String ELEM_EXPENSE = "expense"; //$NON-NLS-1$
	/*
	 * 
	 */
	private static final String ELEM_CATEGORY = "category"; //$NON-NLS-1$
	/*
	 * 
	 */
	private static final String ATTR_NAME = "name"; //$NON-NLS-1$

	/*
	 * The Reader object to use to read the XML document.
	 */
	private Reader reader;

	/**
	 * Returns the {@link Reader} being used to load the XML document.
	 * 
	 * @return The {@code Reader} object.
	 */
	public Reader getReader() {
		return this.reader;
	}

	/**
	 * 
	 * @param reader
	 */
	public void setReader(Reader reader) {
		this.reader = reader;
	}

	/**
	 * 
	 * @return
	 */
	protected Document readDocument() {
		Document doc = null;
		SAXReader reader = new SAXReader();

		try {
			doc = reader.read(this.reader);
		} catch (DocumentException ex) {
			Logger.getLogger(getClass().getName()).log(Level.SEVERE,
					CoreMessages.getString("org.msb.finance.data.CategoryLoader.readDocumentException"), ex); //$NON-NLS-1$
		}

		return doc;
	}

	/**
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Set<Category>[] loadDefaultCategories() {
		Set<Category>[] categorySets = (Set<Category>[]) new Object[2];

		Document doc = readDocument();
		if (null != doc) {
			Element root = doc.getRootElement();

			Element incomeElem = root.element(ELEM_INCOME);
			if (null != incomeElem) {
				categorySets[0] = parseCategories(incomeElem);
			}

			Element expenseElem = root.element(ELEM_EXPENSE);
			if (null != expenseElem) {
				categorySets[1] = parseCategories(expenseElem);
			}
		}

		return categorySets;
	}

	@SuppressWarnings("unchecked")
	private Set<Category> parseCategories(Element sectionElem) {
		List categoryElems = sectionElem.elements(ELEM_CATEGORY);
		HashSet<Category> set = new HashSet<Category>(categoryElems.size());

		for (int i = 0; i < categoryElems.size(); ++i) {
			Element categoryElem = (Element) categoryElems.get(i);
			set.add(parseCategory(categoryElem));
		}

		return set;
	}

	/*
	 * Parses the <category> element passed in and creates a Category object for it, which is
	 */
	@SuppressWarnings("unchecked")
	private Category parseCategory(Element categoryElem) {
		Category category = new Category(categoryElem.attributeValue(ATTR_NAME));

		List categoryElems = categoryElem.elements(ELEM_CATEGORY);
		for (int i = 0; i < categoryElems.size(); ++i) {
			Category subcategory = parseCategory(categoryElem);
			category.addSubCategory(subcategory);
		}

		return null;
	}
}
